﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Yoozoo.Mars.Got;

[ExecuteAlways, ImageEffectAllowedInSceneView]
public class GgamePostEffect : MonoBehaviour
{
    [Header("Bloom")] 
    public bool enableBloom;
    public Shader bloomShader;
    [DisplayOnly]
    public Material bloom;
    
    public float _BlurAmount;
    public Color _BloomColor;
    public float _BloomAmount;
    public float _Threshold;

    private const int BloomPass = 0;
    private const int BlurPass = 1;
    private const int ApplyBloomPass = 2;

    [Header("ColorGrading")] 
    public bool enableGrading;
    public Shader colorGradingShader;
    [DisplayOnly]
    public Material colorGrading;

    public Color _GradingColor;
    [DisplayOnly]
    public Color _GradingMulColor;
    public float _GradingContrast;
    public float _GradingExposure;
    public float _GradingGamma;
    public float _GradingVignetteIntensity;
    public float _GradingSaturation;

    public bool ACES_ON;
    public bool SATURN_ON;
    public bool VIGNETTE_ON;
    
    private float darkPercent;
    private int fadeState;
    private float fadeTime;
    private float fadeStartTime;

    private Image blackScreenImage;

    private void Start()
    {
        if (Application.isPlaying)
        {
            DeviceQuality.Instance.RegisterAction(ChangeQualityAction);
        }

        CheckQuality();
    }

    private void OnDestroy()
    {
        if (Application.isPlaying)
        {
            DeviceQuality.Instance.UnRegisterAction(ChangeQualityAction);
        }
    }

    private void OnEnable()
    {
        
        SetParams();
    }


    void OnRenderImage(RenderTexture source, RenderTexture destination) {
        int width = source.width;
        int height = source.height;
        RenderTextureFormat format = source.format;

        RenderTexture currentDestination = RenderTexture.GetTemporary(width,height,0,format);
        RenderTexture currentSource = source;

        if (enableBloom && bloom)
        {
            Graphics.Blit(currentSource, currentDestination, bloom, BloomPass);

            currentSource = currentDestination;
            currentDestination = RenderTexture.GetTemporary(width, height, 0, format);
            Graphics.Blit(currentSource, currentDestination, bloom, BlurPass);
            RenderTexture.ReleaseTemporary(currentSource);

            currentSource = currentDestination;
            bloom.SetTexture("_BloomTex", source);
            currentDestination = RenderTexture.GetTemporary(width, height, 0, format);
            Graphics.Blit(currentSource, currentDestination, bloom, ApplyBloomPass);
            RenderTexture.ReleaseTemporary(currentSource);

            currentSource = currentDestination;
        }

        if (enableGrading && colorGrading)
        {
            colorGrading.SetColor("_MulColor",_GradingMulColor);
            Graphics.Blit(currentSource, destination, colorGrading);
        }
        else
        {
            Graphics.Blit(currentSource, destination);
        }

        
        RenderTexture.ReleaseTemporary(currentSource);
    }


    void SetParams()
    {
        if (bloomShader && (!bloom || bloom.shader != bloomShader))
        {
            bloom = new Material(bloomShader);
            bloom.hideFlags = HideFlags.HideAndDontSave;
        }

        if (colorGradingShader && (!colorGrading||colorGrading.shader != colorGradingShader))
        {
            colorGrading = new Material(colorGradingShader);
            colorGrading.hideFlags = HideFlags.HideAndDontSave;
        }

        
        if (bloom)
        {
            bloom.SetFloat("_BlurAmount",_BlurAmount);
            bloom.SetColor("_BloomColor",_BloomColor);
            bloom.SetFloat("_BloomAmount",_BloomAmount);
            bloom.SetFloat("_Threshold",_Threshold);
        }

        if (colorGrading)
        {
            colorGrading.SetVector("_Color",_GradingColor);
            colorGrading.SetColor("_MulColor",_GradingMulColor);
            colorGrading.SetFloat("_Contrast",_GradingContrast);
            colorGrading.SetFloat("_Exposure",_GradingExposure);
            colorGrading.SetFloat("_Gamma",_GradingGamma);
            colorGrading.SetFloat("_VignetteIntensity",_GradingVignetteIntensity);
            colorGrading.SetFloat("_Saturation",_GradingSaturation);

            if (ACES_ON) {
                colorGrading.EnableKeyword("ACES_ON");
            }
            else {
                colorGrading.DisableKeyword("ACES_ON");
            }
            
            
            if (SATURN_ON) {
                colorGrading.EnableKeyword("SATURN_ON");
            }
            else {
                colorGrading.DisableKeyword("SATURN_ON");
            }
            
            if (VIGNETTE_ON) {
                colorGrading.EnableKeyword("VIGNETTE_ON");
            }
            else {
                colorGrading.DisableKeyword("VIGNETTE_ON");
            }
        }
    }

    private void ChangeQualityAction<QualityEnum>(QualityEnum qe)
    {
       
            CheckQuality();

       
    }
    /// <summary>
    /// 
    /// </summary>
    private void CheckQuality()
    {
        if (Application.isPlaying)
        {
            var currentQuality = DeviceQuality.Instance.GetCurrentQuality();
            this.enabled = currentQuality == QualityEnum.VeryHigh || currentQuality == QualityEnum.Perfect;
        }
    }
    private void Update()
    {
        if (fadeState != 0)
        {
            var percent = (Time.time - fadeStartTime) / fadeTime;
            if (fadeState == 1)
            {
                darkPercent = percent;
            }
            else
            {
                darkPercent = 1 - percent;
            }

            if (percent >= 1)
            {
                fadeState = 0;
            }
        }
        _GradingMulColor = Color.Lerp(Color.white, Color.black, darkPercent);
        if (blackScreenImage != null)
        {
            var color = Color.black;
            color.a = darkPercent;
            blackScreenImage.color = color;
        }

#if UNITY_EDITOR
        if (!Application.isPlaying)
        { 
            SetParams();
        }
#endif
    }
    
    public void BlackIn(float time)
    {
        fadeState = 1;
        fadeStartTime = Time.time;
        fadeTime = time;
        if (blackScreenImage == null)
        {
            var rootCanvas = GameObject.Find("UIRoot/RootCanvas");
            if (rootCanvas != null)
            {
                var blackScreenImageObj = new GameObject("BlackScreenImage");
                blackScreenImageObj.transform.SetParent(rootCanvas.transform);
                blackScreenImage = blackScreenImageObj.AddComponent<Image>();
                var rect = blackScreenImageObj.GetComponent<RectTransform>();
                rect.sizeDelta = new Vector2(Screen.width, Screen.height);
                blackScreenImage.color = new Color(0,0,0,0);
                blackScreenImage.raycastTarget = false;
            }
        }
    }

    public void BlackOut(float time)
    {
        fadeState = 2;
        fadeStartTime = Time.time;
        fadeTime = time;
    }
    
#if UNITY_EDITOR
    private void OnValidate()
    {
        SetParams();
    }

#endif
    
    
}
